package com.bilin.coin.network.builder;

import com.bilin.coin.network.RetrofitConfig;
import com.bilin.coin.network.api.RetrofitApi;
import com.bilin.coin.network.download.DownLoadListener;
import com.bilin.coin.network.download.DownLoadResponseBody;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Created by LG on 2018/4/15.
 */

public class FileBuilder extends RetrofitRequestBuilder<ResponseBody, FileBuilder> implements HasParamsable {

    /**
     * 目标文件存储的文件夹路径
     */
    public String strDestFileDir="";
    /**
     * 目标文件存储的文件名
     */
    public String strDestFileName="";

    private DownLoadListener mDownLoadListener;

    public void downLoadFile(String destFileDir, String destFileName, DownLoadListener downLoadListener) {

        this.strDestFileDir = destFileDir;

        this.strDestFileName = destFileName;

        this.mDownLoadListener = downLoadListener;

        OkHttpClient okhttpClient = new OkHttpClient.Builder()

                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response response = chain.proceed(chain.request());

                        return response.newBuilder().body(new DownLoadResponseBody(response.body(), mDownLoadListener)).build();
                    }
                })
                .addInterceptor(RetrofitConfig.initRetrofitConfig().getHttpLoggingInterceptor())
                .retryOnConnectionFailure(true)
                .build();

        RetrofitConfig
                .initRetrofitConfig()
                .baseUrl(baseUrl, okhttpClient)
                .build()
                .create(RetrofitApi.class)
                .downloadFile(url, headers, params)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .map(new Function<ResponseBody, InputStream>() {
                    @Override
                    public InputStream apply(ResponseBody responseBody) throws Exception {
                        return responseBody.byteStream();
                    }
                })
                .observeOn(Schedulers.computation())
                .doOnNext(new Consumer<InputStream>() {
                    @Override
                    public void accept(InputStream inputStream) throws Exception {
                        saveFile(inputStream);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<InputStream>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(InputStream inputStream) {
                        mDownLoadListener.onFinishDownload(new File(strDestFileDir+"/"+strDestFileName));
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    @Override
    public Observable<ResponseBody> build() {

        return null;
    }

    @Override
    public FileBuilder params(Map<String, String> params) {
        this.params = params;
        return this;
    }

    @Override
    public FileBuilder addParams(String key, String val) {
        params.put(key, val);
        return this;
    }

    /**
     * 保存文件
     *
     * @param inputStream
     * @throws IOException
     */
    public void saveFile(final InputStream inputStream) throws IOException {

        InputStream is = null;
        byte[] buf = new byte[2048];
        int len = 0;
        FileOutputStream fos = null;
        try {
            is = inputStream;

            long sum = 0;

            File dir = new File(strDestFileDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            File file = new File(dir, strDestFileName);
            fos = new FileOutputStream(file);

            while ((len = is.read(buf)) != -1) {
                sum += len;
                fos.write(buf, 0, len);
                //final long finalSum = sum;
            }
            fos.flush();
            //Thread.sleep(10);



        } catch (FileNotFoundException e) {


        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                if (is != null) is.close();
            } catch (IOException e) {
            }
            try {
                if (fos != null) fos.close();
            } catch (IOException e) {
            }

        }


    }
}
